home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / UPC12BS2.ZIP / RNEWS / HISTORY.C < prev    next >
C/C++ Source or Header  |  1992-11-13  |  14KB  |  423 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    h i s t o r y . c                                               */
  3. /*                                                                    */
  4. /*    News history file maintenance for UUPC/extended.                */
  5. /*                                                                    */
  6. /*    Written by Mike Lipsie                                          */
  7. /*                                                                    */
  8. /*    The history file                                                */
  9. /*                                                                    */
  10. /*    This file describes and implements the history file.            */
  11. /*                                                                    */
  12. /*    The history file is [newsdir]/history and is "added" to by      */
  13. /*    rnews.  It is "pruned" by expire and is used by rnews (to       */
  14. /*    check that the article has not arrived before), expire (to      */
  15. /*    find all copies of the article), and rn (to mark as read all    */
  16. /*    copies of an article.)                                          */
  17. /*                                                                    */
  18. /*    The history file is entirely ASCII.                             */
  19. /*                                                                    */
  20. /*    The first line is a code that identifies the version level      */
  21. /*    (so that future versions can automatically upgrade.)  For       */
  22. /*    version one that code is "ZIP1".                                */
  23. /*                                                                    */
  24. /*    Every line (except the version line) is the record of a         */
  25. /*    single incoming article.  That line is exactly as described     */
  26. /*    without added spaces or other punctuation.  The first field     */
  27. /*    is the Message-ID including (or added if they don't exist),     */
  28. /*    the "<" and ">", a space, the date received (dd/mm/yyyy with    */
  29. /*    days and months being zero filled if necessary), a space,       */
  30. /*    and the "destination" information.                              */
  31. /*                                                                    */
  32. /*    The destination information is the Newsgroups:  with a colon    */
  33. /*    and the article number for each group added (article number     */
  34. /*    zero is used for newsgroups not accepted.)                      */
  35. /*                                                                    */
  36. /*    For example, if article <123@pyramid> was received on 3 Jan     */
  37. /*    1992 and was posted to ba.food, ba.transportation, and          */
  38. /*    soc.singles and ended up in article 4334, 1234, and 56789       */
  39. /*    (respectively), the record would be                             */
  40. /*                                                                    */
  41. /*    <123@pyramid> 03/01/1992                                        */
  42. /*    ba.food:4334,ba.transportation:1234,soc.singles:56789           */
  43. /*                                                                    */
  44. /*    To speed access into the history file there is a parallel       */
  45. /*    file history.ndx which contains information where each day's    */
  46. /*    worth of history records begins.  The first line is a           */
  47. /*    version number and must be the same as that of the history      */
  48. /*    file.  All the other records are the 10 character date code,    */
  49. /*    a space, and a ten digit location code (right justified,        */
  50. /*    zero or blank filled.)  The location code is the byte           */
  51. /*    displacement into the history file of the first record with     */
  52. /*    that date code.                                                 */
  53. /*--------------------------------------------------------------------*/
  54.  
  55.  
  56. /*--------------------------------------------------------------------*/
  57. /*                        System include files                        */
  58. /*--------------------------------------------------------------------*/
  59.  
  60. #include <stdio.h>
  61. #include <stdlib.h>
  62. #include <string.h>
  63. #include <time.h>
  64. #include <fcntl.h>
  65. #include <io.h>
  66. #include <sys/types.h>
  67. #include <sys/stat.h>
  68.  
  69. /*--------------------------------------------------------------------*/
  70. /*                    UUPC/extended include files                     */
  71. /*--------------------------------------------------------------------*/
  72.  
  73. #include "lib.h"
  74. #include "hlib.h"
  75. #include "timestmp.h"
  76. #include "active.h"
  77. #include "history.h"
  78.  
  79. /*  These variables are used to improve the performance of checking
  80.  *  for previous existance of an article.
  81.  *
  82.  *  The basic theory of how this feature works is that a file
  83.  *  (history.dbm) is built with enough information (it is hoped)
  84.  *  to eliminate 99% (well, most) of the non matching message IDs.
  85.  *  A check is made when a match is made confiming that the match
  86.  *  is real.  Since most articles are not "re-sends" (all if you
  87.  *  have only one feed) this won't impose a large overhead.
  88.  *
  89.  *  The information that is used to eliminate unnecessary checks into
  90.  *  the history file for duplicate messageIDs is the first ten
  91.  *  characters of the message ID (not including the leading "<"),
  92.  *  the number of characters in the full ID (including the "<" and ">"),
  93.  *  a checksum of the full ID (also including the "<" and ">"), and
  94.  *  the location in the history file of the full ID.
  95.  *
  96.  *  Additionally, an array of MAXbuf (currently 8) buffers of history.dbm
  97.  *  are maintained in memory to avoid disk I/O.
  98.  *
  99.  */
  100.  
  101. int cur_buff = 0;
  102. int cur_off  = 0;
  103. #define MAXbuf 8
  104.  
  105. char *hb[MAXbuf];
  106. int hb_blk[MAXbuf];
  107.  
  108. extern FILE *hfile;
  109.  
  110. FILE *hdbm_file = NULL;
  111.  
  112. struct perf_elem {
  113.    char IDpart[10];  /* The first 10 characters (after the "<") of the message-ID */
  114.    char cksum;       /* Checksum of the entire ID (including <>) */
  115.    char IDlen;       /* Number of characters in the ID (including <>) */
  116.    long where;       /* ftell() in file of actual record */
  117. };
  118.  
  119.  
  120. /*--------------------------------------------------------------------*/
  121. /*    h i s t o r y _ e x i s t s                                     */
  122. /*                                                                    */
  123. /*    Determine if the history file exists and is a file (instead     */
  124. /*    of a directory).                                                */
  125. /*--------------------------------------------------------------------*/
  126.  
  127. boolean history_exists( void )
  128. {
  129.    char hfile_name[FILENAME_MAX];
  130.    struct stat buff;
  131.  
  132.    mkfilename(hfile_name, E_newsdir, "history");
  133.  
  134.    if ((stat(hfile_name, &buff) == 0) && buff.st_mode & S_IFREG)
  135.       return TRUE;
  136.    else
  137.       return FALSE;
  138.  
  139. } /* history_exists */
  140.  
  141.  
  142. /*--------------------------------------------------------------------*/
  143. /*    o p e n _ h i s t o r y                                         */
  144. /*                                                                    */
  145. /*    Open the history file and verify that it is of the correct      */
  146. /*    version.  If any error occurs, NULL is returned.                */
  147. /*--------------------------------------------------------------------*/
  148.  
  149. #ifdef __TURBOC__
  150. #pragma argsused
  151. #endif
  152.  
  153. FILE *open_history(char *history_date)
  154. {
  155.  
  156. #ifdef NEXT_RELEASE_MAYBE
  157.    char hfile_name[FILENAME_MAX];
  158.    FILE *hfile;
  159.    FILE *index_file;
  160.    char buff[BUFSIZ];
  161.  
  162.    mkfilename(hfile_name, newsdir, "history");
  163.    hfile = fopen(hfile_name, "a+b");
  164.    if (hfile == NULL) {
  165.       printmsg(0,"Unable to open history file");
  166.       return hfile;
  167.    }
  168.    fseek(hfile, 0L, SEEK_SET);
  169.    fgets(buff, sizeof(buff), hfile);
  170.    buff[strlen(buff)-1] = '\0';
  171.    if (buff[strlen(buff)-1] == '\r') buff[strlen(buff)-1] = '\0';
  172.    if ((strlen(buff)) != strlen(H_VERSION)) {
  173.       printmsg(0, "History version incorrect");
  174.       return NULL;
  175.    }
  176.    if (!equal(buff, H_VERSION)) {
  177.       printmsg(0, "History version incorrect");
  178.       return NULL;
  179.    }
  180.  
  181.  
  182.    fseek(hfile, 0L, SEEK_END);